home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 317 / asmsrc / frags.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  6.8 KB  |  234 lines

  1. /* frags.c - manage frags - */
  2.  
  3. /* Copyright (C) 1987 Free Software Foundation, Inc.
  4.  
  5. This file is part of Gas, the GNU Assembler.
  6.  
  7. The GNU assembler is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY.  No author or distributor
  9. accepts responsibility to anyone for the consequences of using it
  10. or for whether it serves any particular purpose or works at all,
  11. unless he says so in writing.  Refer to the GNU Assembler General
  12. Public License for full details.
  13.  
  14. Everyone is granted permission to copy, modify and redistribute
  15. the GNU Assembler, but only under the conditions described in the
  16. GNU Assembler General Public License.  A copy of this license is
  17. supposed to have been given to you along with the GNU Assembler
  18. so you can know your rights and responsibilities.  It should be
  19. in a file named COPYING.  Among other things, the copyright
  20. notice and this notice must be preserved on all copies.  */
  21.  
  22. #include "as.h"
  23. #include "subsegs.h"
  24. #include "obstack.h"
  25. #include "frags.h"
  26. #include "struc-symbol.h"
  27.  
  28. struct obstack  frags;    /* All, and only, frags live here. */
  29.  
  30. fragS zero_address_frag = {
  31.     0,            /* fr_address */
  32.     NULL,            /* fr_next */
  33.     0,            /* fr_fix */
  34.     0,            /* fr_var */
  35.     0,            /* fr_symbol */
  36.     0,            /* fr_offset */
  37.     NULL,            /* fr_opcode */
  38.     rs_fill,        /* fr_type */
  39.     0,            /* fr_subtype */
  40.     0            /* fr_literal [0] */
  41. };
  42.  
  43. fragS bss_address_frag = {
  44.     0,            /* fr_address. Gets filled in to make up
  45.                    sy_value-s. */
  46.     NULL,            /* fr_next */
  47.     0,            /* fr_fix */
  48.     0,            /* fr_var */
  49.     0,            /* fr_symbol */
  50.     0,            /* fr_offset */
  51.     NULL,            /* fr_opcode */
  52.     rs_fill,        /* fr_type */
  53.     0,            /* fr_subtype */
  54.     0            /* fr_literal [0] */
  55. };
  56.  
  57. /*
  58.  *            frag_grow()
  59.  *
  60.  * Internal.
  61.  * Try to augment current frag by nchars chars.
  62.  * If there is no room, close of the current frag with a ".fill 0"
  63.  * and begin a new frag. Unless the new frag has nchars chars available
  64.  * do not return. Do not set up any fields of *now_frag.
  65.  */
  66. static  void
  67. frag_grow (nchars)
  68. int     nchars;
  69. {
  70.     if (obstack_room (&frags) < nchars) {
  71.     frag_wane (frag_now);
  72.     frag_new (0);
  73.     }
  74.     if (obstack_room (&frags) < nchars)
  75.     as_fatal ("Can't extend frag %d. chars", nchars);
  76. }
  77.  
  78. /*
  79.  *            frag_new()
  80.  *
  81.  * Call this to close off a completed frag, and start up a new (empty)
  82.  * frag, in the same subsegment as the old frag.
  83.  * [frchain_now remains the same but frag_now is updated.]
  84.  * Because this calculates the correct value of fr_fix by
  85.  * looking at the obstack 'frags', it needs to know how many
  86.  * characters at the end of the old frag belong to (the maximal)
  87.  * fr_var: the rest must belong to fr_fix.
  88.  * It doesn't actually set up the old frag's fr_var: you may have
  89.  * set fr_var == 1, but allocated 10 chars to the end of the frag:
  90.  * in this case you pass old_frags_var_max_size == 10.
  91.  *
  92.  * Make a new frag, initialising some components. Link new frag at end
  93.  * of frchain_now.
  94.  */
  95. void
  96. frag_new (old_frags_var_max_size)
  97. int     old_frags_var_max_size;    /* Number of chars (already allocated on
  98.                    obstack frags) */
  99.  /* in variable_length part of frag. */
  100. {
  101.     register    fragS * former_last_fragP;
  102. /*    char   *throw_away_pointer; JF unused */
  103.     register    frchainS * frchP;
  104.     long    tmp;        /* JF */
  105.  
  106.     frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
  107.     (frag_now->fr_literal) - old_frags_var_max_size;
  108.  /* Fix up old frag's fr_fix. */
  109.  
  110.     obstack_finish (&frags);
  111.  /* This will align the obstack so the */
  112.  /* next struct we allocate on it will */
  113.  /* begin at a correct boundary. */
  114.     frchP = frchain_now;
  115.     know (frchP);
  116.     former_last_fragP = frchP->frch_last;
  117.     know (former_last_fragP);
  118.     know (former_last_fragP == frag_now);
  119.     obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
  120.  /* We expect this will begin at a correct */
  121.  /* boundary for a struct. */
  122.     tmp=obstack_alignment_mask(&frags);
  123.     obstack_alignment_mask(&frags)=0;        /* Turn off alignment */
  124.                             /* If we ever hit a machine
  125.                            where strings must be
  126.                            aligned, we Lose Big */
  127.  frag_now=(fragS *)obstack_finish(&frags);
  128.     obstack_alignment_mask(&frags)=tmp;        /* Restore alignment */
  129. /*    obstack_unaligned_done (&frags, &frag_now); */
  130. /*    know (frags.obstack_c_next_free == frag_now->fr_literal); */
  131.  /* Generally, frag_now->points to an */
  132.  /* address rounded up to next alignment. */
  133.  /* However, characters will add to obstack */
  134.  /* frags IMMEDIATELY after the struct frag, */
  135.  /* even if they are not starting at an */
  136.  /* alignment address. */
  137.     former_last_fragP->fr_next = frag_now;
  138.     frchP->frch_last = frag_now;
  139.     frag_now->fr_next = NULL;
  140. }                /* frag_new() */
  141.  
  142. /*
  143.  *            frag_more()
  144.  *
  145.  * Start a new frag unless we have n more chars of room in the current frag.
  146.  * Close off the old frag with a .fill 0.
  147.  *
  148.  * Return the address of the 1st char to write into. Advance
  149.  * frag_now_growth past the new chars.
  150.  */
  151.  
  152. char   *
  153. frag_more (nchars)
  154. int     nchars;
  155. {
  156.     register char  *retval;
  157.  
  158.     frag_grow (nchars);
  159.     retval = obstack_next_free (&frags);
  160.     obstack_blank_fast (&frags, nchars);
  161.     return (retval);
  162. }                /* frag_more() */
  163.  
  164. /*
  165.  *            frag_var()
  166.  *
  167.  * Start a new frag unless we have max_chars more chars of room in the current frag.
  168.  * Close off the old frag with a .fill 0.
  169.  *
  170.  * Set up a machine_dependent relaxable frag, then start a new frag.
  171.  * Return the address of the 1st char of the var part of the old frag
  172.  * to write into.
  173.  */
  174.  
  175. char   *
  176. frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
  177.         relax_stateT type;
  178. int     max_chars;
  179. int     var;
  180. relax_substateT subtype;
  181. symbolS * symbol;
  182. long int    offset;
  183. char   *opcode;
  184. {
  185.     register char  *retval;
  186.  
  187.     frag_grow (max_chars);
  188.     retval = obstack_next_free (&frags);
  189.     obstack_blank_fast (&frags, max_chars);
  190.     frag_now->fr_var = var;
  191.     frag_now->fr_type = type;
  192.     frag_now->fr_subtype = subtype;
  193.     frag_now->fr_symbol = symbol;
  194.     frag_now->fr_offset = offset;
  195.     frag_now->fr_opcode = opcode;
  196.     frag_new (max_chars);
  197.     return (retval);
  198. }                /* frag_var() */
  199.  
  200. /*
  201.  *            frag_wane()
  202.  *
  203.  * Reduce the variable end of a frag to a harmless state.
  204.  */
  205. void
  206. frag_wane (fragP)
  207. register    fragS * fragP;
  208. {
  209.     fragP->fr_type = rs_fill;
  210.     fragP->fr_offset = 0;
  211.     fragP->fr_var = 0;
  212. }
  213.  
  214. /*
  215.  *            frag_align()
  216.  *
  217.  * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);".
  218.  * Foo & bar are absolute integers.
  219.  *
  220.  * Call to close off the current frag with a ".align", then start a new
  221.  * (so far empty) frag, in the same subsegment as the last frag.
  222.  */
  223.  
  224. void
  225. frag_align (alignment, fill_character)
  226. int     alignment;
  227. int     fill_character;
  228. {
  229.     *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0,
  230.  (long)alignment, (char *)0)) = fill_character;
  231. }
  232.  
  233. /* end: frags.c */
  234.